package com.shopping.alarm.ding;

import com.shopping.alarm.ding.message.AbstractMessage;
import com.shopping.alarm.properties.DingTalkConfig;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 异常报警
 * <p>
 * https://developers.dingtalk.com/document/app/custom-robot-access
 *
 * @author zengweilong
 */
@Slf4j
@Data
public class DingTalkMessage {


    @Autowired
    protected DingTalkConfig dingTalkConfig;

    @Autowired
    protected Environment environment;

    @Autowired
    private RestTemplate restTemplate;


    public void sendCoreMessage(AbstractMessage message) throws Exception {

        if (!dingTalkConfig.getEnable()) {
            log.info("Ding message send Enable is:{}", dingTalkConfig.getEnable());
            return;
        }

        String jsonBody = message.toJson();
        String dingUrl = message.getDingTalkUrl();
        // 默认URL推送
        if (StringUtils.isBlank(dingUrl)) {
            dingUrl = dingTalkConfig.getUrl();
        }
        if (StringUtils.isBlank(dingUrl)) {
            log.warn("Pleads check the properties [ ding.talk.url ] in file [ application.yml ]");
            return;
        }

        Long timestamp = System.currentTimeMillis();
        String sign = getSign(timestamp);
        dingUrl = String.format(dingUrl, timestamp, sign);

        log.info("Send ding talk message...");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> request = new HttpEntity<>(jsonBody, headers);
        ResponseEntity<String> postForEntity = restTemplate.postForEntity(dingUrl, request, String.class);

        log.info("Send ding talk message end = {}", postForEntity.getBody());
    }


    public String getSign(Long timestamp) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        String secret = dingTalkConfig.getSecret();
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        return sign;
    }

    public String getHostName() {
        String hostInfo;
        try {
            hostInfo = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException ignored) {
            log.warn("Get host fail", ignored);
            hostInfo = "unknown-host";
        }
        return hostInfo;
    }

    public String getHostIp() {
        String ipInfo;
        try {
            ipInfo = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException ignored) {
            log.warn("Get ip fail", ignored);
            ipInfo = "unknown-ip";
        }
        return ipInfo;
    }

    public String getEnv() {
        String[] env = environment.getActiveProfiles();
        if (env != null && env.length > 0) {
            return env[0] + "_";
        }
        env = environment.getDefaultProfiles();
        if (env != null && env.length > 0) {
            return env[0] + "_";
        }
        return StringUtils.EMPTY;
    }

}
